/* eslint-disable vue/script-setup-uses-vars */
<template>
  <el-form
    ref="formRef"
    :model="form"
    :label-width="formPattern.labelWidth"
    :rules="rules"
    label-position="left"
    v-if="form != undefined && formPattern.formItem != undefined"
  >
    <div v-for="(item, index) in formPattern.formItem" :key="index">
      <div v-if="item.type != 'multi' && item.type != 'form-item-list'">
        <el-form-item
          :label="item.label + ':'"
          :prop="item.prop"
          label-width="auto"
        >
          <!-- el-input -->
          <el-input
            v-if="item.type === 'el-input'"
            v-model="form[item.prop]"
            :placeholder="item.placeholder"
            :disabled="item.isReadOnly"
            style="width:1020px"
          ></el-input>
          <el-input-number
            v-if="item.type == 'el-input-number'"
            v-model="form[item.prop]"
            :placeholder="item.placeholder"
            :disabled="item.isReadOnly"
            style="width:1020px"
            :controls="false"
            :precision="item.precision != undefined ? item.precision : 2"
            :max="item.max"
            :min="item.min"
          ></el-input-number>
          <!--  <el-autpcomplete> -->
          <el-autocomplete
            v-if="item.type === 'el-autocomplete'"
            v-model="form[item.prop]"
            style="width:1020px"
            :fetch-suggestions="
              (queryString, cb) =>
                querySearch(
                  queryString,
                  cb,
                  item.prop,
                  item.type,
                  formPattern.formType,
                  index
                )
            "
          >
            <template #suffix>
              <i class="el-icon-edit el-input__icon"> </i>
            </template>
            <template #default="{ item }">
              <span>{{ item.value }}</span>
            </template>
          </el-autocomplete>
          <!-- el-date-picker -->
          <el-date-picker
            v-if="item.type === 'el-date-picker'"
            v-model="form[item.prop]"
            type="date"
            style="width:1020px"
          >
          </el-date-picker>
          <!-- el-select -->
          <el-select
            collapse-tags
            v-if="item.type === 'el-select'"
            v-model="form[item.prop]"
            style="width:1020px"
          >
            <el-option
              v-for="option in item.options"
              :key="option.value"
              :label="option.label"
              :value="option.value"
            ></el-option>
          </el-select>
          <!-- el-cascader -->
          <el-cascader
            v-if="item.type === 'el-cascader'"
            :options="item.options"
            v-model="form[item.prop]"
            style="width:1020px"
            @change="
              val => {
                changeCascader(val, form);
              }
            "
          ></el-cascader>
          <!-- end -->
        </el-form-item>
      </div>
      <!-- landingAgency and partner -->
      <!-- 刚开始offsetList不存在？ -->
      <div
        class="multi-form-item"
        v-else-if="item.offsetList && item.type == 'multi'"
      >
        <el-button
          plain
          type="info"
          @click="addMultiItem(item.prop)"
          style="margin-bottom: 20px; margin-left: -140px"
          v-if="item.isShowAddButton"
          >{{ item.label }}</el-button
        >
        <!-- 没有数据的时候不渲染该组件，这样不会出现unexpected width的bug -->
        <div
          v-if="
            form[item.prop] != undefined && form[item.prop]?.length != undefined
          "
        >
          <el-row
            v-for="(multiDataItem, rowIndex) in form[item.prop]"
            :key="rowIndex.key"
          >
            <!-- 行里面的每个formItem-->
            <!-- e.g (col, 0) in [agencyName, shareRadio] -->
            <!-- KNOW THAT activateDataItem is a OBJECT!!! -->
            <el-col
              v-for="(keyName, keyIndex) in item.keyList"
              :key="keyIndex.key"
              :span="item.spanList[keyIndex]"
              :offset="item.offsetList[keyIndex]"
            >
              <!-- if want to add some text after a item -->
              <span v-if="item.itemType[keyIndex] === 'text'">{{
                item.labelList[keyIndex]
              }}</span>
              <!-- col里面的form-item -->
              <!-- eg prop= landingAgencies.0.agencyName -->
              <el-form-item
                :label="item.labelList[keyIndex] + ':'"
                :prop="`${item.prop}.${rowIndex}.${keyName}`"
                :rules="rules.subRule[keyName]"
                label-width="auto"
                v-if="item.itemType[keyIndex] !== 'text'"
              >
                <!-- e.g v-model="landingAgency[0].agencyName" -->
                <el-input
                  v-model="multiDataItem[keyName]"
                  :disabled="item.isDisabled[keyIndex]"
                  v-if="item.itemType[keyIndex] === 'el-input'"
                  clearable
                ></el-input>
                <el-input-number
                  v-model="multiDataItem[keyName]"
                  :disabled="item.isDisabled[keyIndex]"
                  v-if="item.itemType[keyIndex] === 'el-input-number'"
                  :precision="2"
                  :controls="false"
                  :min="0"
                  :max="100"
                  clearable
                ></el-input-number>
                <!-- el-autocomplete -->
                <el-autocomplete
                  v-model="multiDataItem[keyName]"
                  clearable
                  v-if="item.itemType[keyIndex] === 'el-autocomplete'"
                  :fetch-suggestions="
                    (queryString, cb) =>
                      querySearch(
                        queryString,
                        cb,
                        keyName,
                        item.type,
                        formPattern.formType,
                        rowIndex
                      )
                  "
                ></el-autocomplete>
                <!-- el-date-picker -->
                <el-date-picker
                  v-if="item.itemType[keyIndex] === 'el-date-picker'"
                  v-model="multiDataItem[keyName]"
                  type="date"
                  style="width:150px"
                >
                </el-date-picker>
                <!-- el-select -->
                <el-select
                  collapse-tags
                  v-if="item.itemType[keyIndex] === 'el-select'"
                  v-model="multiDataItem[keyName]"
                  :disabled="item.isDisabled[keyIndex]"
                >
                  <el-option
                    v-for="subOption in item.subOptions[keyName]"
                    :key="subOption.value"
                    :label="subOption.label"
                    :value="subOption.value"
                  ></el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <!-- delete button -->
            <el-col :span="1" :offset="1">
              <el-button
                type="danger"
                icon="el-icon-delete"
                style="margin-left: 10px"
                @click.prevent="deleteMultiItem(item.prop, rowIndex)"
                :disabled="form[item.prop]?.length <= 1"
              ></el-button>
            </el-col>
          </el-row>
        </div>
      </div>
      <!-- 只用过修改落地机构的返款时间.根据数据的不同会渲染不同个数的form-item -->
      <div
        v-else-if="
          item.type == 'form-item-list' && form[item.prop] != undefined
        "
      >
        <el-form-item
          v-for="(subItem, subIndex) in form[item.prop]"
          :key="subIndex"
          :label="
            labelFormatter(
              item.insertIndex,
              item.label,
              (subIndex + 1).toString(),
              item.type
            )
          "
          label-width="auto"
        >
          <el-date-picker
            v-if="item.formItemListType == 'el-date-picker'"
            v-model="subItem[item.key]"
            type="date"
          ></el-date-picker>
          <el-input-number
            v-model="subItem[item.key]"
            v-else-if="item.formItemListType === 'el-input-number'"
            :precision="2"
            :controls="false"
            :min="0"
            clearable
          ></el-input-number>
        </el-form-item>
      </div>
    </div>
    <!-- submit -->
    <el-form-item>
      <el-button type="primary" @click="submitValidate()" id="submit-button"
        >提交</el-button
      >
    </el-form-item>
  </el-form>
</template>

<script lang="ts">
import { computed, defineComponent, PropType, reactive, ref } from "vue";
import { LandingAgency, Partners, Project } from "@/interface/entity";
import { FormPattern } from "@/interface/general";
import { useRoute, useRouter } from "vue-router";
import { CodeToText } from "element-china-area-data";
import store from "@/store";
import { constObjs } from "@/const/const";
import { labelFormatter, uniqueArr } from "@/functions/general";
import { ElMessage } from "element-plus";

export default defineComponent({
  name: "MyForm",
  props: {
    formPattern: {
      // 从显式类型推断 props
      type: Object as PropType<FormPattern>,
      required: true
    },
    myForm: {
      type: Object,
      required: true
    },
    rules: {
      type: Object,
      required: true
    },
    // 子组件表单通过验证以后，执行父组件的表单提交操作
    validSubmit: {
      type: Function,
      required: true
    }
  },
  setup(props) {
    // 级联选择器变化
    const changeCascader = (val: never[], form: object) => {
      switch (props.myForm.formType) {
        case "project": {
          const thisForm = form as Project;
          let area = "";
          val.forEach(element => {
            area = area.concat(CodeToText[element]);
            area += " ";
          });
          thisForm.selectedArea = area;
          break;
        }
      }
    };
    // 表单验证ref
    const formRef = ref();
    // router
    const route = useRoute();
    const router = useRouter();

    // 获取搜索建议
    const querySearch = (
      queryString: string,
      cb: Function,
      prop: string,
      type: string,
      formType: string,
      index: number
    ) => {
      const querySearchResult = [] as { value: string }[];
      if (type == "multi") {
        // todo
        return;
      } else {
        // todo
        // if (formType == "project") {

        // }
        // 找出匹配的projectlist并选出其projectmanager构成一个字符串数组返回
        (store.state.tableData as object[])
          .filter(data =>
            (data[prop as keyof object] as string)
              .toLowerCase()
              .includes(queryString.toLowerCase())
          )
          .forEach(item => {
            querySearchResult.push({
              value: item[prop as keyof object] as string
            });
          });
      }
      console.log(queryString, prop, type, formType);
      // console.log(
      //   "已去重",
      //   uniqueArr<{ value: string }>(querySearchResult, "value")
      // );
      // console.log("未去重", querySearchResult);
      // 把去重的结果给cb回调
      cb(uniqueArr<{ value: string }>(querySearchResult, "value"));
    };

    const submitValidate = async () => {
      try {
        await formRef.value.validate((valid: boolean) => {
          if (valid) {
            props.validSubmit();
            // 对store中的form重新赋默认值
            switch (route.name) {
              case "incomestreamsystem": {
                store.state.editingForm = JSON.parse(
                  JSON.stringify(constObjs.incomeStreamForm)
                );
                store.state.formPattern = JSON.parse(
                  JSON.stringify(constObjs.incomeStreamFormPattern)
                );
                break;
              }
              case "outlaystreamsystem": {
                store.state.editingForm = JSON.parse(
                  JSON.stringify(constObjs.outlayStreamForm)
                );
                store.state.formPattern = JSON.parse(
                  JSON.stringify(constObjs.outlayStreamFormPattern)
                );
                break;
              }
            }
          } else {
            ElMessage.error("提交失败");
          }
        });
      } catch (error) {
        console.log(error);
      }
    };

    // ------------multi-------------------
    // 为表单中的multi项添加row
    const addMultiItem = (prop: string) => {
      switch (prop) {
        case "landingAgencies": {
          ((store.state.editingForm as Project)
            .landingAgencies as LandingAgency[]).push({
            agencyName: "",
            shareRadio: 0,
            shareAmount: 0
            // rebateTime: ""
          });
          break;
        }
        case "partners": {
          ((store.state.editingForm as Project).partners as Partners[]).push({
            partnerName: "",
            shareRadio: 0,
            shareAmount: 0,
            // rebateTime: "",
            partnerType: "",
            // 默认按比例计算
            caculation: "比例"
          });
          break;
        }
      }
    };
    // 删除表单的eltable的row
    const deleteMultiItem = (prop: string, index: number) => {
      switch (prop) {
        case "landingAgencies": {
          ((store.state.editingForm as Project)
            .landingAgencies as LandingAgency[]).splice(index, 1);
          break;
        }
        case "partners": {
          ((store.state.editingForm as Project).partners as Partners[]).splice(
            index,
            1
          );
          break;
        }
      }
    };
    // ------------multi-------------------

    return reactive({
      changeCascader,
      // 子组件获取父组件的参数并copy，保持reactive,让form object在子组件可以被修改
      form: computed(() => props.myForm),
      route,
      router,
      labelFormatter: computed(() => labelFormatter),
      querySearch,
      addMultiItem,
      deleteMultiItem,
      submitValidate,
      formRef
    });
  }
});
</script>

<style scoped>
#submit-button {
  margin-left: 32%;
}
.el-form {
  margin: 50px 15% 0 21%;
}
.el-col-1 > span {
  font-size: 20px;
}
.el-col-1 {
  line-height: 40px;
}
.el-autocomplete-suggestion__list {
  /* 选择器在一行显示 */
  display: block;
}
.el-input-number .el-input .el-input__inner {
  text-align: left;
}
input .el-input__inner {
  text-align: left;
}
/* 继承父亲宽度 */
.el-input-number {
  width: 100%;
}
li {
  display: block;
}
.el-form-item__label,
.el-dialog__body {
  color: #000000;
}
</style>
